﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace PPTHelper
{

    public class HttpResutl
    {
        public Dictionary<string, string> Headers = new Dictionary<string, string>();
        public byte[] ByteArray { get; private set; } = new byte[0];
        public string TextContent => Encoding.UTF8.GetString(ByteArray);
        public HttpResutl(string content) => ByteArray = Encoding.UTF8.GetBytes(content);
        public HttpResutl(byte[] Bytes) => ByteArray = Bytes;
    }

    class HttpServer
    {
        public static int Port { get; set; }
        readonly HttpListener listener;
        public Dictionary<string, Func<HttpListenerRequest, HttpResutl>> RouteFunc { get; set; }

        public HttpServer(int port = 8080)
        {
            Port = port;
            RouteFunc = new Dictionary<string, Func<HttpListenerRequest, HttpResutl>>
            {
                { "/hi", (req) => new HttpResutl( "Hello world!") }
            };
            listener = new HttpListener();
            listener.Prefixes.Add($"http://*:{Port}/");
        }

        public void Start()
        {
            Log.Info($"Server started at http://*:{Port}");
            Task.Run(async () =>
            {
                listener.Start();
                while (true)
                {
                    var context = await listener.GetContextAsync();
                    try
                    {
                        var request = context.Request;
                        Log.Info($"HttpServer：{request.RemoteEndPoint}：{request.HttpMethod}：{request.RawUrl}");
                        var path = request.Url.AbsolutePath;
                        if (RouteFunc.ContainsKey(path))
                        {
                            //回调
                            var result = RouteFunc[path].Invoke(request);
                            if (result != null)
                            {
                                var response = context.Response;
                                foreach (var item in result.Headers) { response.Headers[item.Key] = item.Value; }
                                using (var stream = context.Response.OutputStream)
                                {
                                    response.ContentLength64 = result.ByteArray.Length;
                                    stream.Write(result.ByteArray, 0, result.ByteArray.Length);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Warn($"HttpServer：{ex.Message}");
                    }
                    finally
                    {
                        Log.Info($"HttpServer：ContentLength {context.Response.ContentLength64} Byte");
                        context.Response.Close();
                    }
                }
            });
        }

        public void Stop() => listener.Close();

    }
}
